-- Bishop
-- Create by panyl
-- 主教对象

Bishop = {
    classId = 0,
    hp     = 0,
    mp     = 0,
    level  = 0,
    skills  = {},

    -- 对象类型为主教
    type = OBJECT_TYPE_BISHOP,
};
Bishop.__index = Bishop;

-- 构造函数
function Bishop.new(classId, data)
    local self = {};
    setmetatable(self, Bishop);
    self.classId = classId;
    self.dbase = Dbase.new(data);

    for key, value in pairs(data) do
        self[key] = value;
    end

    -- 设置主教的数据
    if data.level ~= nil then
        self.level = data.level
    end

    -- 如果有技能
    if data.skills ~= nil then
        self:setSkills(data.skills);
    else
        self:setSkills({});
    end

    return self;
end

-- 取得该对象的描述字符串
function Bishop:get_ob_id()
    return string.format("Bishop:%s", tostring(self.classId));
end

-- 查找数据
function Bishop:query(path, path2, default)
    local value = self.dbase:query(path, path2, default);
    if value then
        return value;
    end

    if path == "classId" or path == "class_id" then
        return self.classId;
    elseif path == "level"  then return self.level;
    elseif path == "hp" then
        return FormulaM.invoke("BISHOP_BASE_HP");
    elseif path == "mp" then
        return FormulaM.invoke("BISHOP_BASE_MP");
    elseif path == "max_hp" then
        return FormulaM.invoke("CALC_BISHOP_MAX_HP", self);
    elseif path == "max_mp" then
        return FormulaM.invoke("CALC_BISHOP_MAX_MP", self);
    elseif path == "attack" then
        return FormulaM.invoke("CALC_BISHOP_ATTACK", self);
    elseif path == "magic" then
        return FormulaM.invoke("CALC_BISHOP_MAGIC", self);
    else
        return BishopM.query(self.classId, path);
    end
end

-- 设置血量
function Bishop:setHp(hp)
    local add = hp - self:getHp(false);
    local baseHp = self.dbase:query("hp", 0) + add;

    self.dbase:set("hp", baseHp);

    BishopM.syncBishopData();
end

-- 设置魔法值
function Bishop:setMp(mp)
    local add = mp - self:getMp(false);
    local baseMp = self.dbase:query("mp", 0) + add;

    self.dbase:set("mp", baseMp);

    BishopM.syncBishopData();
end

-- 主教后天技能
function Bishop:getSkills()
    -- 所有后天学习的技能
    return self.skills;
end

-- 主教所有技能
function Bishop:getAllSkills()
    return self:getSkills();
end

-- 查询属性
function Bishop:queryAttrib(attrib, args)
    return AttribM.queryAttrib(self, attrib, args);
end

-- 计算最大血量
function Bishop:getMaxHp()
    return FormulaM.invoke("CALC_BISHOP_MAX_HP", self);
end

-- 当前血量
function Bishop:getHp(fix)
    if fix == nil then
        -- 默认需要修正
        fix = true;
    end

    return FormulaM.invoke("CALC_BISHOP_HP", self, fix);
end

-- 获取魔法值
function Bishop:getMp(fix)
    if fix == nil then
        -- 默认需要修正
        fix = true;
    end

    return FormulaM.invoke("CALC_BISHOP_MP", self, fix);
end

-- 获取最大魔法值
function Bishop:getMaxMp()
    return FormulaM.invoke("CALC_BISHOP_MAX_MP", self);
end

-- 计算基础攻击值
function Bishop:getAttack()
    return FormulaM.invoke("CALC_BISHOP_ATTACK", self);
end

-- 计算基础魔法值
function Bishop:getMagic()
    return FormulaM.invoke("CALC_BISHOP_MAGIC", self);
end

-- 命中
function Bishop:getAccuracy()
    -- 暂时用玩家的命中
    return FormulaM.invoke("CALC_USER_ACCURACY", ME.user);
end

-- 闪避
function Bishop:getDodge()
    -- 暂时用玩家的闪避
    return FormulaM.invoke("CALC_USER_DODGE", ME.user);
end

-- 获取等级
function Bishop:getLevel()
    return self.level or 0;
end

-- 名称
function Bishop:getName()
    return self:query("name");
end

-- 获取属主
function Bishop:getOwner()
    return BishopM.getBishopPos();
end

function Bishop:getPos()
    return BishopM.getBishopPos();
end

-- 受到伤害
function Bishop:receiveDamage(damage)
    local hp = self.dbase:query("hp", 0) - damage;

    self.dbase:set("hp", hp);

    BishopM.syncBishopData();

    local msg = string.format("[Bishop]%s收到伤害：%d，当前hp：%d，max_hp：%d",
        self:getName(), damage, self:getHp(false), self:getMaxHp());
    DungeonLogM.addLog(msg);

    -- 抛出主教受创事件
    EventMgr.fire(event.BISHOP_DAMAGED, {["bishop"] = self, ["damage"] = damage, });

    return hp;
end

-- 死亡
function Bishop:die()
    if self:getHp() > 0 then
        return false;
    end

    DungeonLogM.addLog("[Bishop]主教死亡了。");

    -- 标记死亡
    self.dbase:set("is_dead", 1);

    BishopM.syncBishopData();

    EventMgr.fire(event.BISHOP_DIE);

    return true;
end

-- 是否已死亡
function Bishop:isDead()
    -- 有死亡标志
    if 1 == self.dbase:query("is_dead") then
        return true;
    end

    return false;
end

-- 复活
function Bishop:revive(hp, mp)
    self:setHp(hp);
    self:setMp(mp);

    self.dbase:delete("is_dead");

    -- 刷新下属性
    PropM.refresh(self);

    DungeonLogM.addLog("主教复活了。");
end

-- 主教是否有技能
function Bishop:ownSkill(skillId)
    return tonumber(self.skills[skillId]) > 0;
end

-- 技能等级
function Bishop:getSkillLevel(skillId)
    return tonumber(self.skills[skillId]);
end

-- 设置等级
function Bishop:setLevel(level)
    self.level = level;
end

-- 设置技能
function Bishop:setSkills(skills)
    self.skills = skills;
end

-- 升级技能，这里不做检查
function Bishop:upgradeSkill(skillId)
    self.skills[skillId] = (self.skills[skillId] or 0) + 1;
end

-- 学习技能
function Bishop:learnSkill(skillId)
    self.skills[skillId] = 1;
end

-- 获取数据
function Bishop:getSaveData()
    local ret = {
        ["class_id"] = self.classId,
        ["level"]    = self.level,
        ["action"]   = self.action,
        ["hp"]       = self.dbase:query("hp"),
        ["mp"]       = self.dbase:query("mp"),
        ["is_dead"]  = self.dbase:query("is_dead"),
        ["skill_round"] = self.skill_round,
    };

    local skills = self:getAllSkills();
    if #table.keys(skills) > 0 then
        ret["skills"] = self:getAllSkills();
    end

    return ret;
end
